//! 语法分析器模块
//! 
//! 将词法单元序列转换为抽象语法树（AST）

mod core;
mod instruction;
mod operand;

pub use core::Parser;

#[cfg(test)]
mod tests {
    use super::*;
    use crate::ast::{Operand, Statement};

    #[test]
    fn test_parse_simple_instruction() {
        let source = "移动 累加器，10";
        let mut parser = Parser::from_source(source).unwrap();
        let program = parser.parse_program().unwrap();
        
        assert_eq!(program.statements.len(), 1);
        if let Statement::Instruction(inst) = &program.statements[0] {
            assert_eq!(inst.name, "移动");
            assert_eq!(inst.operands.len(), 2);
            assert!(matches!(inst.operands[0], Operand::Register(_)));
            assert!(matches!(inst.operands[1], Operand::Immediate(10)));
        } else {
            panic!("期望是指令");
        }
    }

    #[test]
    fn test_parse_reg_reg_instruction() {
        let source = "移动 累加器，基址";
        let mut parser = Parser::from_source(source).unwrap();
        let program = parser.parse_program().unwrap();
        
        if let Statement::Instruction(inst) = &program.statements[0] {
            assert_eq!(inst.name, "移动");
            assert_eq!(inst.operands.len(), 2);
            if let (Operand::Register(dst), Operand::Register(src)) = (&inst.operands[0], &inst.operands[1]) {
                assert_eq!(dst, "累加器");
                assert_eq!(src, "基址");
            } else {
                panic!("期望是寄存器到寄存器");
            }
        }
    }

    #[test]
    fn test_parse_label() {
        let source = "开始：\n移动 累加器，10";
        let mut parser = Parser::from_source(source).unwrap();
        let program = parser.parse_program().unwrap();
        
        assert_eq!(program.statements.len(), 2);
        if let Statement::Label(name, _) = &program.statements[0] {
            assert_eq!(name, "开始");
        } else {
            panic!("期望是标签");
        }
    }

    #[test]
    fn test_parse_memory_operand_simple() {
        let source = "移动 累加器，【10】";
        let mut parser = Parser::from_source(source).unwrap();
        let program = parser.parse_program().unwrap();
        
        if let Statement::Instruction(inst) = &program.statements[0] {
            if let Operand::Memory(mem) = &inst.operands[1] {
                assert_eq!(mem.displacement, Some(10));
                assert_eq!(mem.base, None);
                assert_eq!(mem.index, None);
            } else {
                panic!("期望是内存操作数");
            }
        }
    }

    #[test]
    fn test_parse_memory_operand_base() {
        let source = "移动 累加器，【基址】";
        let mut parser = Parser::from_source(source).unwrap();
        let program = parser.parse_program().unwrap();
        
        if let Statement::Instruction(inst) = &program.statements[0] {
            if let Operand::Memory(mem) = &inst.operands[1] {
                assert_eq!(mem.base, Some("基址".to_string()));
                assert_eq!(mem.index, None);
            } else {
                panic!("期望是内存操作数");
            }
        }
    }

    #[test]
    fn test_parse_memory_operand_base_index() {
        let source = "移动 累加器，【基址+源索引】";
        let mut parser = Parser::from_source(source).unwrap();
        let program = parser.parse_program().unwrap();
        
        if let Statement::Instruction(inst) = &program.statements[0] {
            if let Operand::Memory(mem) = &inst.operands[1] {
                assert_eq!(mem.base, Some("基址".to_string()));
                assert_eq!(mem.index, Some("源索引".to_string()));
            } else {
                panic!("期望是内存操作数");
            }
        }
    }

    #[test]
    fn test_parse_memory_operand_base_displacement() {
        let source = "移动 累加器，【基址+10】";
        let mut parser = Parser::from_source(source).unwrap();
        let program = parser.parse_program().unwrap();
        
        if let Statement::Instruction(inst) = &program.statements[0] {
            if let Operand::Memory(mem) = &inst.operands[1] {
                assert_eq!(mem.base, Some("基址".to_string()));
                assert_eq!(mem.displacement, Some(10));
            } else {
                panic!("期望是内存操作数");
            }
        }
    }

    #[test]
    fn test_parse_negative_immediate() {
        let source = "移动 累加器，-10";
        let mut parser = Parser::from_source(source).unwrap();
        let program = parser.parse_program().unwrap();
        
        if let Statement::Instruction(inst) = &program.statements[0] {
            if let Operand::Immediate(imm) = inst.operands[1] {
                assert_eq!(imm, -10);
            } else {
                panic!("期望是立即数");
            }
        }
    }

    #[test]
    fn test_parse_jump_instruction() {
        let source = "跳转 标签";
        let mut parser = Parser::from_source(source).unwrap();
        let program = parser.parse_program().unwrap();
        
        if let Statement::Instruction(inst) = &program.statements[0] {
            assert_eq!(inst.name, "跳转");
            assert!(matches!(inst.operands[0], Operand::Label(_)));
        }
    }

    #[test]
    fn test_parse_multiple_instructions() {
        let source = "移动 累加器，10\n加 累加器，20\n减 累加器，5";
        let mut parser = Parser::from_source(source).unwrap();
        let program = parser.parse_program().unwrap();
        
        assert_eq!(program.statements.len(), 3);
    }

    #[test]
    fn test_parse_arithmetic_instructions() {
        let source = "加 累加器，基址\n减 累加器，10\n自增 累加器\n自减 累加器";
        let mut parser = Parser::from_source(source).unwrap();
        let program = parser.parse_program().unwrap();
        
        assert_eq!(program.statements.len(), 4);
    }

    #[test]
    fn test_parse_error_missing_operand() {
        // 注意：解析器本身允许缺少操作数，错误会在编码阶段检测
        // 这个测试验证解析器可以解析缺少操作数的指令（虽然会在后续阶段报错）
        let source = "移动 累加器";
        let mut parser = Parser::from_source(source).unwrap();
        let result = parser.parse_program();
        // 解析器会成功，但指令只有1个操作数（应该在编码阶段报错）
        if let Ok(program) = result {
            if let Statement::Instruction(inst) = &program.statements[0] {
                assert_eq!(inst.operands.len(), 1); // 只有1个操作数，缺少第二个
            }
        } else {
            // 如果解析失败也可以接受
            assert!(result.is_err());
        }
    }

    #[test]
    fn test_parse_error_invalid_syntax() {
        let source = "移动 累加器，";
        let mut parser = Parser::from_source(source).unwrap();
        let result = parser.parse_program();
        assert!(result.is_err());
    }
}

